using System;
using FireStarter.Base;
using FireStarter.Base.BusinessObjectMerger;
using Firestarter.Test.Base.BusinessObjectMerger;
using FireStarterModeller.BO;
using FireStarterModeller.Test.BO;
using Habanero.Base;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.Smooth;
using Habanero.Testability;
using NUnit.Framework;
namespace FireStarterModeller.Test.Logic.MergeBusinessObjects
{
    [TestFixture]
    public class TestMergeDMObjects
    {
        [TestFixtureSetUp]
        public virtual void TestFixtureSetup()
        {
            TestUtilsLogic.SetupFixture();
            AllClassesAutoMapper.ClassDefCol = ClassDef.ClassDefs;
            ClassDefCol classDefCol = typeof (FakeMergeableParent).Assembly.MapClasses();
            ClassDef.ClassDefs.Add(classDefCol);
        }

        [SetUp]
        public virtual void SetupTest()
        {
            TestUtilsLogic.SetupTest();
        }



        [Test]
        public void Test_MatchBusinessObject_WhenBOsMatch_ShouldRetTrue()
        {
            //---------------Set up test pack-------------------
            MergeBO<DMPropRule> mergeBO = new MergeBO<DMPropRule>();
            var propRule = new DMPropRule
                    {
                       PropRuleName = TestUtilsShared.GetRandomString()
                    };
            var propRule2 = new DMPropRule
                    {
                        PropRuleName = propRule.PropRuleName
                    };
            //---------------Assert Precondition----------------
            Assert.AreEqual(propRule.PropRuleName, propRule2.PropRuleName);
            //---------------Execute Test ----------------------
            bool matchBO = mergeBO.MatchBusinessObject(propRule).Invoke(propRule2);
            //---------------Test Result -----------------------
            Assert.IsTrue(matchBO);
        }

        [Test]
        public void Test_MatchBusinessObject_WhenBOsDoNotMatch_ShouldRetFalse()
        {
            //---------------Set up test pack-------------------
            MergeBO<DMPropRule> mergeBO = new MergeBO<DMPropRule>();
            var propRule = new DMPropRule
                    {
                       PropRuleName = TestUtilsShared.GetRandomString()
                    };
            var propRule2 = new DMPropRule
                    {
                        PropRuleName = TestUtilsShared.GetRandomString()
                    };
            //---------------Assert Precondition----------------
            Assert.AreNotEqual(propRule.PropRuleName, propRule2.PropRuleName);
            //---------------Execute Test ----------------------
            bool matchBO = mergeBO.MatchBusinessObject(propRule).Invoke(propRule2);
            //---------------Test Result -----------------------
            Assert.IsFalse(matchBO);
        }


        [Test]
        public void Test_MergeSingleRel_WhenMergeFromRelatedBONull_ShouldDoNothing()
        {
            //---------------Set up test pack-------------------
            MergeBOSpy mergeBO = new MergeBOSpy();
            DMClass @class = new DMClass();
            SingleRelationship<DMAssembly> singleRel1 = (SingleRelationship<DMAssembly>)@class.Relationships["Assembly"];
            DMClass @class2 = new DMClass();

            SingleRelationship<DMAssembly> singleRel2 = (SingleRelationship<DMAssembly>)@class2.Relationships["Assembly"];
            var expectedRelBO = new DMAssembly();
            singleRel2.SetRelatedObject(expectedRelBO);
            //---------------Assert Precondition----------------
            Assert.IsNull(singleRel1.GetRelatedObject());
            Assert.AreSame(expectedRelBO, singleRel2.GetRelatedObject());
            //---------------Execute Test ----------------------
            mergeBO.CallMergeSingleRelationship(singleRel1, singleRel2);
            //---------------Test Result -----------------------
            Assert.IsNull(singleRel1.GetRelatedObject());
            Assert.AreSame(expectedRelBO, singleRel2.GetRelatedObject());
        }

        [Test]
        public void Test_MergeSingle_WhenNoFromSingleObject_ShouldMarkPendingChangesDelete()
        {
            //---------------Set up test pack-------------------
            IMergeBO<UIGridInfo> mergeBO = MergeableBORegistry.Instance.Resolve<UIGridInfo>();
            var fromGrid = TestUtilsUIGridInfo.CreateUnsavedValidUIGridInfo_WNoUIView();
            var toGrid = new UIGridInfo();
            var toGridFilter = new UIGridFilter
            {
                Columns = RandomValueGen.GetRandomInt()
            };
            toGrid.UIGridFilter = toGridFilter;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(toGrid.UIGridFilter);
            Assert.IsNull(fromGrid.UIGridFilter);
            //---------------Execute Test ----------------------
            mergeBO.MergeBOFrom(fromGrid, toGrid);
            //---------------Test Result -----------------------
            Assert.IsNotNull(toGrid.UIGridFilter);
            Assert.AreEqual(ChangeType.Delete, ((IMergableBo)toGrid.UIGridFilter).PendingChangeType);
        }


        [Test]
        public void Test_BOIsDirty_WhenFalse_ShouldNotBeSetToTrueIfPropUpdatedToSaveValue()
        {
            //---------------Set up test pack-------------------
            var solution = TestUtilsDMSolution.CreateSavedDMSolution();
            //---------------Assert Precondition----------------
            Assert.IsFalse(solution.Status.IsDirty);
            //---------------Execute Test ----------------------
            solution.SolutionName = solution.SolutionName;
            //---------------Test Result -----------------------
            Assert.IsFalse(solution.Status.IsDirty);
        }

        [Test]
        public void Test_IgnoresGenerateCodeProperty()
        {
            //---------------Set up test pack-------------------

            DMSolution dmSolutionOriginal = TestUtilsShared.CreateSavedDMSolution();
            DMClass oldClass = TestUtilsDMClass.CreateSavedDMClass(dmSolutionOriginal);
            oldClass.GenerateCode = false;
            DMSolution dmSolutionNew = TestUtilsShared.CreateSavedDMSolution();
            DMClass newClass = TestUtilsDMClass.CreateSavedDMClass(dmSolutionNew);
            newClass.ClassNameBO = oldClass.ClassNameBO;
            newClass.GenerateCode = true;
            var merger = MergeableBORegistry.Instance.Resolve<DMSolution>();
            //---------------Execute Test ----------------------
            merger.MergeBOFrom(dmSolutionOriginal, dmSolutionNew);
            //---------------Test Result -----------------------
            Assert.IsFalse(oldClass.GenerateCode);
        }

        [Test]
        public void Test_IgnoresNeedsRegenerationProperty()
        {
            //---------------Set up test pack-------------------

            DMSolution dmSolutionOriginal = TestUtilsShared.CreateSavedDMSolution();
            DMClass oldClass = TestUtilsDMClass.CreateSavedDMClass(dmSolutionOriginal);
            oldClass.NeedsRegeneration = true;
            DMSolution dmSolutionNew = TestUtilsShared.CreateSavedDMSolution();
            DMClass newClass = TestUtilsDMClass.CreateSavedDMClass(dmSolutionNew);
            newClass.ClassNameBO = oldClass.ClassNameBO;
            newClass.NeedsRegeneration = false;
            var merger = MergeableBORegistry.Instance.Resolve<DMSolution>();
            //---------------Execute Test ----------------------
            merger.MergeBOFrom(dmSolutionOriginal, dmSolutionNew);
            //---------------Test Result -----------------------
            Assert.IsTrue(oldClass.NeedsRegeneration);
        }
/*
        private string GetValidPropValue(Expression<Func<DMSolution, string>> propExpression)
        {
            return TestUtilsDMSolution.GetTestFactory().GetValidPropValue(propExpression);
        }*/
    }
/*
    public class MockBo2 : BusinessObject
    {
        public string TestStringProp
        {
            get { return (string)GetPropertyValue("TestStringProp"); }
            set { SetPropertyValue("TestStringProp", value); }
        }

        public override string ToString()
        {
            return TestStringProp;
        }
    }*/
}